package com.kosmos.dubhe.wxcp.provider;

import com.kosmos.dubhe.wxcp.config.EnvironmentHolder;
import com.kosmos.dubhe.wxcp.config.WxCpConfiguration;
import com.kosmos.dubhe.wxcp.setting.WxcpSenderSetting;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.NoSuchElementException;
import java.util.Objects;


/**
 * @author wukai
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class WxCpMessageSender implements DisposableBean {

    private final EnvironmentHolder environment;

    private final WxCpUserProvider provider;
    private final WxCpTagProvider tagProvider;
    private final WxCpDepartmentProvider departmentProvider;
    private final WxcpSenderSetting setting;


    @PostConstruct
    public void init() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd HH:mm");
        var now = formatter.format(LocalDateTime.now());
        var content = setting.getFirstMessageTitle() + "@" + now + " start...\r\n不要回答不要回答不要回答!!!\r\n[" + environment.getActiveProfilesName() + "]";
        WxCpMessage reply = WxCpMessage.TEXT().toUser(setting.getFirstMessageUserCode()).content(content).build();
        log.debug("WxCpMessageSender init reply:{} ", reply);
        sendMessage(setting.getDefaultAgentId(), reply);
    }


    @Override
    public void destroy() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd HH:mm");
        var now = formatter.format(LocalDateTime.now());
        var content = setting.getFirstMessageTitle() + "@" + now + " bye...\r\n[" + environment.getActiveProfilesName() + "]";
        WxCpMessage reply = WxCpMessage.TEXT().toUser(setting.getFirstMessageUserCode()).content(content).build();
        log.debug("WxCpMessageSender destroy:{} ", reply);
        sendMessage(setting.getDefaultAgentId(), reply);
    }


    private void sendMessage(Integer agentId, WxCpMessage message) {
        try {
            WxCpConfiguration.getCpService(agentId).getMessageService().send(message);
        } catch (WxErrorException e) {
            log.error("", e);
        }
    }

    public void broadcastMessageDefaultChannel(MessageType messageType, String tagId, String content) {
        broadcastMessage(setting.getDefaultAgentId(), messageType, tagId, content);
    }

    public void broadcastMessageToTagNameDefaultChannel(MessageType messageType, String tagName, String content) {
        String t = tagProvider.getTagCode(tagName);
        broadcastMessageDefaultChannel(messageType, t, content);
    }

    public void broadcastPartyMessageDefaultChannel(MessageType messageType, String tagName,
                                                    String content) {
        Long t = departmentProvider.getDepartmentId(tagName);
        broadcastPartyMessageDefaultChannel(messageType, t, content);
    }

    public void broadcastPartyMessageDefaultChannel(MessageType messageType,
                                                    Long departmentId,
                                                    String content) {
        broadcastPartyMessage(setting.getDefaultAgentId(), messageType, departmentId, content);
    }

    public void broadcastMultiUserNameMessageDefaultChannel(MessageType messageType,
                                                            String[] multiName,
                                                            String content) {
        Arrays.stream(multiName)
                .forEach(userName -> alertMessage(setting.getDefaultAgentId(), messageType, userName, content));

    }

    /**
     * 广播消息(按tagId发送)
     *
     * @param agentId
     * @param messageType
     * @param departmentId
     * @param content
     */
    public void broadcastPartyMessage(Integer agentId, MessageType messageType, Long departmentId, String content) {
        sendMessage(agentId, messageType.build(content).toParty(String.valueOf(departmentId)).build());
    }

    /**
     * 广播消息(按tagId发送)
     *
     * @param agentId
     * @param messageType
     * @param tagId
     * @param content
     */
    public void broadcastMessage(Integer agentId, MessageType messageType, String tagId, String content) {
        sendMessage(agentId, messageType.build(content).toTag(tagId).build());
    }

    public void notifyMessageDefaultChannel(MessageType messageType, String userCode, String content) {
        notifyMessage(setting.getDefaultAgentId(), messageType, userCode, content);
    }

    /**
     * 点对点消息(按userCode发送)
     *
     * @param agentId
     * @param messageType
     * @param userCode
     * @param content
     */
    public void notifyMessage(Integer agentId, MessageType messageType, String userCode, String content) {
        sendMessage(agentId, messageType.build(content).toUser(userCode).build());
    }

    public void alertMessageDefaultChannel(MessageType messageType, String userName, String content) {
        alertMessage(setting.getDefaultAgentId(), messageType, userName, content);
    }

    /**
     * 提醒消息(按userName发送)
     *
     * @param agentId
     * @param messageType
     * @param userName
     * @param content
     */
    public void alertMessage(Integer agentId, MessageType messageType, String userName, String content) {
        if (Objects.isNull(agentId)) {
            throw new RuntimeException("agentId must be not null");
        }
        try {
            notifyMessage(agentId, messageType, provider.getUserCode(userName.trim()), content);
        } catch (NoSuchElementException e) {
            log.error("WxCpMessageSender alertMessage occur exception ", e);
            // bywukai
            if (Objects.nonNull(setting.getFirstMessageUserCode())) {
                notifyMessage(agentId, MessageType.TEXT, setting.getFirstMessageUserCode(), String.format("user --> userName[%s] not found in wechat", userName));
            } else {
                broadcastMessage(agentId, MessageType.TEXT, setting.getFirstMessageTag(), String.format("user --> userName[%s] not found in wechat", userName));
            }
        }
    }
}
